package net.qhzw.vip.qiyu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.constant.LoginConstant;
import net.qhzw.vip.qiyu.entity.DtsUser;
import net.qhzw.vip.qiyu.entity.SysUser;
import net.qhzw.vip.qiyu.handler.ApiException;
import net.qhzw.vip.qiyu.model.LoginForm;
import net.qhzw.vip.qiyu.model.LoginUser;
import net.qhzw.vip.qiyu.model.Resource;
import net.qhzw.vip.qiyu.service.*;
import net.qhzw.vip.qiyu.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysLoginServiceImpl implements SysLoginService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private DtsUserService dtsUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;


    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Value("${jwt.expiration}")
    private Long expiration;


    /***
     * 后台管理人员登录
     * @param param
     * @return
     */
    @Override
    public LoginUser login(LoginForm param) {
        LoginUser loginUser = null;
        //密码需要客户端加密后传递
        try {
            UserDetails userDetails = loadUserByUsername(param.getUsername(), param.getLoginType());
            if (!new BCryptPasswordEncoder().matches(param.getPassword(), userDetails.getPassword())) {
                Asserts.fail("密码不正确");
            }
            if (!userDetails.isEnabled()) {
                Asserts.fail("帐号已被禁用");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
                    null,
                    userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            //String token = tokenHead + jwtTokenUtil.generateToken(userDetails);
            String token = "";
            loginUser = new LoginUser();
            loginUser.setUsername(param.getUsername());
            loginUser.setAccess_token(token);
            loginUser.setExpire(expiration);
            loginUser.setRoleCode("user");
            loginUser.setUserId("1");
            return loginUser;
        } catch (AuthenticationException e) {
            log.warn("登录异常:{}", e.getMessage());
            throw new ApiException(e.getMessage());
        }

    }


    public UserDetails loadUserByUsername(String username, String loginType) {
        UserDetails userDetails = null;
        switch (loginType) {
            case LoginConstant.ADMIN_TYPE:
                userDetails = loadSysUserByUsername(username);
                break;
            case LoginConstant.MEMBER_TYPE:
                userDetails = loadMemberUserByUsername(username);
                break;
            default:
                throw new AuthenticationServiceException("暂不支持的登录方式:" + loginType);
        }
        return userDetails;
    }

    private UserDetails loadMemberUserByUsername(String username) {
        DtsUser user = dtsUserService.getUserByUsername(username);
        if (user != null) {
            return new User(String.valueOf(user.getId()),
                    user.getPassword(),
                    user.getStatus() == 1,
                    true,
                    true,
                    true,
                    getSysUserPermissions(user.getId()));
        }
        throw new UsernameNotFoundException(username + "用户不存在！");
    }

    private UserDetails loadWeiXinUserByUsername(String username) {
        DtsUser user = null;
        List<DtsUser> list = dtsUserService.list(new LambdaQueryWrapper<DtsUser>()
                .eq(DtsUser::getUserLevel, 0)
                .eq(DtsUser::getUsername, username));
        if (!CollectionUtils.isEmpty(list)) {
            user = list.get(0);
        }
        if (user != null) {
            return new User(String.valueOf(user.getId()),
                    user.getPassword(),
                    user.getStatus() == 1,
                    true,
                    true,
                    true,
                    getSysUserPermissions(user.getId()));
        }
        throw new UsernameNotFoundException(username + "用户不存在！");
    }

    private UserDetails loadSysUserByUsername(String username) {
        //获取用户信息
        SysUser user = sysUserService.getUserByUsername(username);
        if (user != null) {
            List<Resource> resourceList = getResourceList(user.getId());
            return new User(String.valueOf(user.getId()),
                    user.getPassword(),
                    user.getStatus() == 1,
                    true,
                    true,
                    true,
                    getSysUserPermissions(user.getId()));
        }
        throw new UsernameNotFoundException(username + "用户不存在！");
    }

    private List<Resource> getResourceList(Long id) {
        return Arrays.asList(new Resource(1L, "基础管理", "sys.base.manager"));
    }


    /***
     *查询这个用户对应的权限
     * 通过用户的id 查询用户的权限
     * @param id
     * @return
     */
    private Collection<? extends GrantedAuthority> getSysUserPermissions(Long id) {
        try {
            // 1 当用户为超级管理员时，他拥有所有的权限数据
            String roleCode = sysRoleService.getRoleNameById(id);
            //String roleCode = jdbcTemplate.queryForObject(LoginConstant.QUERY_ROLE_CODE_SQL, String.class, id);
            //String roleCode = "admin";
            List<String> permissions = null; // 权限的名称
            if (LoginConstant.ADMIN_ROLE_CODE.equals(roleCode)) { // 超级用户
                //permissions = jdbcTemplate.queryForList(LoginConstant.QUERY_ALL_PERMISSIONS, String.class);
            } else { // 2 普通用户，需要使用角色->权限数据
                //permissions = jdbcTemplate.queryForList(LoginConstant.QUERY_PERMISSION_SQL, String.class, id);
            }
            if (permissions == null || permissions.isEmpty()) {
                return Collections.emptySet();
            }
            return permissions.stream()
                    .distinct() // 去重
                    .map(perm -> new SimpleGrantedAuthority(perm))
                    .collect(Collectors.toSet());
        } catch (Exception e) {
            return null;
        }

    }

    public List<String> getPermissions(Long id) {
        return Arrays.asList("notice_query", "notice_create", "notice_update");
    }


}
